package com.bocloud.cmp.service.resource;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.dao.CloudVendorDao;
import com.bocloud.cmp.dao.PortDao;
import com.bocloud.cmp.dao.RegionDao;
import com.bocloud.cmp.dao.SubnetDao;
import com.bocloud.cmp.driver.providers.intf.SubnetProvider;
import com.bocloud.cmp.entity.resource.CloudVendor;
import com.bocloud.cmp.entity.resource.Port;
import com.bocloud.cmp.entity.resource.Region;
import com.bocloud.cmp.entity.resource.Subnet;
import com.bocloud.cmp.enums.VendorType;
import com.bocloud.cmp.interfaces.resource.SubnetService;
import com.bocloud.cmp.model.SubnetModel;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.MapTools;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Maps;

/**
 * 子网Service接口实现
 * 
 * @author dongkai
 *
 */
@Service("subnetService")
public class SubnetServiceImpl implements SubnetService {

    private static Logger logger = LoggerFactory.getLogger(SubnetServiceImpl.class);
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private SubnetDao subnetDao;
    @Autowired
    private CloudVendorDao cloudVendorDao;
    @Autowired
    private RegionDao regionDao;
    @Autowired
    private SubnetProvider subnetProvider;
    @Autowired
    private PortDao portDao;

    @Override
    public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
        List<Subnet> list = null;
        List<SimpleBean> beans = null;
        int total = 0;
        GridBean gridBean = null;
        try {
            if (null == sorter) {
                sorter = Maps.newHashMap();
            }
            sorter.put("id", Common.ONE);
            total = subnetDao.count(params);
            if (simple) {
                beans = subnetDao.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                list = this.subnetDao.list(page, rows, params, sorter);
                gridBean = GridHelper.getBean(page, rows, total, list);
            }
            return new BsmResult(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("Query subnet list fail:", e);
            return new BsmResult(false, "查询失败", null, null);
        }
    }

    @Override
    public BsmResult create(String params) {
        JSONObject object = JSONTools.isJSONObj(params);
        Long id = object.getLong(Common.ID);
        Long region = object.getLong(Common.REGION);
        String name = object.getString(Common.NAME);
        String networkId = object.getString("networkId");
        String start = object.getString("start");
        String end = object.getString("end");
        String cidr = object.getString("cidr");
        String gateway = object.getString("gateway");
        BsmResult bsmResult = null;
        Region reg = null;
        try {
            CloudVendor cloudVendor = cloudVendorDao.query(id);
            if (null == cloudVendor) {
                logger.error("get cloudVendor failure!");
                return new BsmResult(false, "创建失败!");
            }
            if (!VendorType.OPENSTACK.name().equals(cloudVendor.getType())) {
                reg = regionDao.query(region);
                if (null == reg) {
                    logger.error("get region failure!");
                    return new BsmResult(false, "创建失败!");
                }
            }
            Map<String, Object> param = MapTools.simpleMap("name", name);
            param.put("networkId", networkId);
            param.put("start", start);
            param.put("end", end);
            param.put("cidr", cidr);
            param.put("gateway", gateway);
            SubnetModel model = JSONObject.parseObject(JSONObject.toJSONString(param), SubnetModel.class);
            if (null == reg) {
                bsmResult = subnetProvider.create(cloudVendor.getUuid(), null, model);
            } else {
                bsmResult = subnetProvider.create(cloudVendor.getUuid(), reg.getCode(), model);
            }
            if (null == bsmResult || !bsmResult.isSuccess()) {
                return new BsmResult(false, "创建失败!");
            }
            Subnet subnet = JSONObject.parseObject(JSONObject.toJSONString(bsmResult.getData()), Subnet.class);
            subnet.setVendorId(id);
            subnet.setRegion(region);
            subnet.setGateway(gateway);
            subnet.setStart(start);
            subnet.setEnd(end);
            subnetDao.save(subnet);
            return new BsmResult(true, "创建成功!");
        } catch (Exception e) {
            logger.error("create subnet failure:", e);
            return new BsmResult(false, "创建失败!");
        }
    }

    @Override
    public BsmResult remove(Long id) {
        String path = Subnet.class.getSimpleName() + "_" + id;
        HarmonyLock lock = null;
        Boolean result = false;
        try {
            lock = lockFactory.getLock(path);
            if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
                logger.warn("Get harmonyLock time out!");
                return new BsmResult(false, "请求超时", "", "");
            }
            Subnet subnet = subnetDao.query(id);
            if (null == subnet) {
                logger.warn("subnet data not exist");
                return new BsmResult(false, "数据不存在", "", "");
            }
            List<Port> ports = portDao.list(subnet.getVendorId(), subnet.getSubnetId());
            if (!ports.isEmpty()) {
                logger.warn("ports is not null");
                return new BsmResult(false, "此子网关联相关端口，无法删除!");
            }
            // 云供应商
            CloudVendor cloudVendor = cloudVendorDao.query(subnet.getVendorId());
            Region region = regionDao.query(subnet.getRegion());
            if (null == cloudVendor || null == region) {
                logger.error("get cloudVendor and region failure");
                return new BsmResult(false, "删除失败", "", "");
            }
            BsmResult bsmResult = subnetProvider.remove(subnet.getSubnetId(), cloudVendor.getUuid(), region.getCode());
            if (null == bsmResult || !bsmResult.isSuccess()) {
                return new BsmResult(false, "删除失败");
            }
            result = subnetDao.delete(id);
        } catch (Exception e) {
            logger.error("remove subnet fail:", e);
            return new BsmResult(false, "删除失败", "", "");
        } finally {
            if (null != lock) {
                lock.release();
            }
        }
        return result ? new BsmResult(true, "删除成功") : new BsmResult(false, "删除失败", "", "");

    }

    @Override
    public BsmResult detail(Long id) {
        try {
            Subnet subnet = subnetDao.query(id);
            return new BsmResult(true, subnet, "查询成功!");
        } catch (Exception e) {
            logger.error("query subnet detail failure:", e);
            return new BsmResult(false, "查询详情失败!");
        }
    }

}
